package com.bo.lock.reentrantLock;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @Author: gpb
 * @Date: 2024/9/3 15:09
 * @Description:
 */
public class IConditionObject {
    public static void main (String[] args) throws InterruptedException {
        Lock lock = new ReentrantLock();
        Condition condition = lock.newCondition();

        new Thread(() -> {
            lock.lock();
            System.out.println(Thread.currentThread().getName() + " 获取到锁资源并await挂起线程并释放锁资源");
            try {
                Thread.sleep(10000);
                condition.await();
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            System.out.println(Thread.currentThread().getName() + " 线程被唤醒,持有锁资源");
        }, "lock-1").start();

        new Thread(() -> {
            lock.lock();
            System.out.println(Thread.currentThread().getName() + " 获取到锁资源并await挂起线程并释放锁资源");
            try {
                Thread.sleep(20000);
                condition.await();
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            System.out.println(Thread.currentThread().getName() + " 线程被唤醒,持有锁资源");
        }, "lock-2").start();

        new Thread(() -> {
            lock.lock();
            System.out.println(Thread.currentThread().getName() + " 获取到锁资源并await挂起线程并释放锁资源");
            try {
                Thread.sleep(30000);
                condition.await();
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            System.out.println(Thread.currentThread().getName() + " 线程被唤醒,持有锁资源");
        }, "lock-3").start();

        Thread.sleep(120000);
        lock.lock();
        System.out.println(Thread.currentThread().getName() + " 拿到锁资源,子线程执行await方法");
        condition.signal();
        System.out.println(Thread.currentThread().getName() + " 执行 signal,主线程唤醒await的线程");
        lock.unlock();

        System.out.println("=====================================");

        new Thread(() -> {
            System.out.println(Thread.currentThread().getName() + " wait ~");
            synchronized (IConditionObject.class){
                try {
                    Thread.sleep(3000);
                    IConditionObject.class.wait();
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
                System.out.println(Thread.currentThread().getName() + " 被唤醒");
            }
        }, "sync").start();

        Thread.sleep(1000);
        synchronized (IConditionObject.class){
            System.out.println(Thread.currentThread().getName() + " notify");
            IConditionObject.class.notify();
        }
    }
}
